
package com.dkm.orproject.utils.utils;

import com.alibaba.druid.filter.config.ConfigTools;
import com.dkm.orproject.dkmoa.domain.OaLog;
import com.dkm.orproject.dkmoa.service.OaLogService;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 工具类
 * @author liandyao
 * @date 2017年9月29日 上午11:30:10
 * @version 1.0
 *
 * @author 原作者
 * @update 修改人
 * @date 修改时间
 * 修改内容.................
 */
@Component
public class Tools {


    @Resource
    OaLogService logService;
    /**
     * 分页每页显示条数
     */
    public final static int PAGES_MAX_RESULT = 5;

    /**
     * 是否有效 有效
     */
    public final static String ISVA_YES = "有效";

    /**
     * 是否有效 无效
     */
    public final static String ISVA_NO = "无效";

    /**
     * 日期格式
     * yyyy-MM-dd
     */
    public static SimpleDateFormat SDF_DATE = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 时间格式
     * yyyy-MM-dd HH:mm:ss
     */
    public static SimpleDateFormat SDF_TIME = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 时间格式
     * yyyy-MM-dd HH:mm:ss
     */
    public static SimpleDateFormat SDF_TIME_NO = new SimpleDateFormat("yyyyMMddHHmmss");

    static Random random = new Random();

    static char[] char_random = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '2', '3', '4', '5', '6', '7', '8', '9', '0'};

    /**
     * 随机生成字符串 共40位
     * @return 随机字符串
     */
    public static String getRandomString() {
        String s = RandomStringUtils.random(20, char_random);
        String s1 = RandomStringUtils.random(20, char_random);
        return s + s1;
    }

    /**
     * 随机生成字符串
     * @param size 位
     * @return 随机字符串
     */
    public static String getRandomString(int size) {
        String s = RandomStringUtils.random(size, char_random);
        return s;
    }

    /**
     * 得到
     * @return
     */
    public static String getRandomUUID() {
        String s = UUID.randomUUID().toString().replaceAll("-", "");
        return s;
    }

    /**
     * 得到随机数字
     * @param num
     * @return
     */
    public static int getRandomNumber(int num) {
        int n = random.nextInt(num);
        return n;
    }

    /**
     * 提供字符串判断是否为空
     * @param input
     * @return input为空返回true
     */
    public static boolean isEmpty(String input) {
        return null == input || 0 == input.length() || 0 == input.replaceAll("\\s", "").length();
    }

    /**
     * 判断集合是否为空
     * @param list
     * @return list为空返回true
     */
    public static boolean isEmpty(List list) {
        if (list == null) return true;
        return list.isEmpty();
    }

    /**
     * 得到当前日期
     * yyyy-MM-dd
     * @return 格式化的r日期字符串
     */
    public static String getCurDate() {
        Date date = new Date();
        return SDF_DATE.format(date);
    }

    /**
     * 得到当前日期时间
     * yyyy-MM-dd HH:mm:ss
     * @return 格式化的r日期字符串
     */
    public static String getCurDateTime() {
        Date date = new Date();
        return SDF_TIME.format(date);
    }

    /**
     * 返回日期格式
     * yyyy-MM-dd
     * @param date
     * @return 格式化的r日期字符串
     */
    public static String getDateStr(Date date) {
        if (date == null) return "";
        return SDF_DATE.format(date);
    }

    /**
     * 返回时间格式
     * yyyy-MM-dd HH:mm:ss
     * @param date
     * @return 格式化的r日期字符串
     */
    public static String getTimeStr(Date date) {
        if (date == null) return "";
        return SDF_TIME.format(date);
    }

    /**
     * 得到订单编码格式:日期格式如:20161222211800,分别代表的是年月日时分秒+5位随机字符串
     * @return
     */
    public static String getDateOrderNo() {
        Date date = new Date();
        String temp = SDF_TIME_NO.format(date);
        temp = temp + getRandomString(10);
        return temp;
    }

    /**
     * 得到订单编码格式:日期格式如:20161222211800,分别代表的是年月日时分秒+5位随机字符串
     * @return
     */
    public static String getDateOrderNumber() {
        Date date = new Date();
        String temp = SDF_TIME_NO.format(date);
        temp = temp + getRandomNumber(5);
        return temp;
    }

    /**
     * 得到多少月份之后的时间
     * @param size 多少月
     * @return 返回字符串
     */
    public static String getAfterDate(int size) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MONTH, size);

        Date date = cal.getTime();
        String str = SDF_DATE.format(date);
        return str;
    }

    /**
     * 与当前时间比
     * @param date
     * @return 如果未超过返回true，如果已经超过返回false
     * @throws ParseException
     */
    public static boolean isDateBefore(String date) throws ParseException {
        if (isEmpty(date)) {
            return false;
        }
        Date exp = SDF_TIME.parse(date);
        Date now = new Date();
        return now.before(exp);
    }

    /**
     * 获取前一天日期yyyyMMdd
     * @return 返回的日期格式为yyyyMMdd
     */
    public static String getYestoday() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        return SDF_DATE.format(calendar.getTime());
    }

    /**
     * 将首字母大写
     * @param name 属性名
     * @return 例如传入属性name, 得到的结果是Name
     */
    public static String firstUpp(String name) {
        if (isEmpty(name)) return name;
        char first = name.charAt(0);
        String newName = Character.toUpperCase(first) + name.substring(1);
        return newName;
    }

    /**
     * 将字符串编码,utf-8格式
     * @param str
     * @return
     */
    public static String encode(String str) {
        try {
            return URLEncoder.encode(str, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 字符解码
     * @param  chinese 该方法默认会以UTF-8解码字符串
     *  若想自己指定字符集,可以使用<code>decode(String chinese, String charset)</code>方法
     */
    public static String decode(String chinese) {
        return decode(chinese, "UTF-8");
    }

    /**
     * 字符解码
     *  该方法通常用于对中文进行解码
     *   若系统不支持指定的解码字符集,则直接将<code>chinese</code>原样返回
     */
    public static String decode(String chinese, String charset) {
        chinese = (chinese == null ? "" : chinese);
        try {
            return URLDecoder.decode(chinese, charset);
        } catch (UnsupportedEncodingException e) {

            return chinese;
        }
    }

    /**
     * 得到当前时间戳,1970年到目前的秒数
     * @return 时间戳
     */
    public static String getTimeStamp() {
        return System.currentTimeMillis() / 1000 + "";
    }

    /**
     * 获取系统流水号
     *  若欲指定返回值的长度or是否全由数字组成等,you can call
     * @return 长度为20的全数字
     */
    public static String getSysJournalNo() {
        return getSysJournalNo(20, true);
    }

    /**
     * 获取系统流水号
     * @param length   指定流水号长度
     * @param isNumber 指定流水号是否全由数字组成
     */
    public static String getSysJournalNo(int length, boolean isNumber) {
        //replaceAll()之后返回的是一个由十六进制形式组成的且长度为32的字符串
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        if (uuid.length() > length) {
            uuid = uuid.substring(0, length);
        } else if (uuid.length() < length) {
            for (int i = 0; i < length - uuid.length(); i++) {
                uuid = uuid + Math.round(Math.random() * 9);
            }
        }
        if (isNumber) {
            return uuid.replaceAll("a", "1").replaceAll("b", "2").replaceAll("c", "3").replaceAll("d", "4").replaceAll("e", "5").replaceAll("f", "6");
        } else {
            return uuid;
        }
    }

    /**
     * 金额元转分
     *  注意:该方法可处理贰仟万以内的金额,且若有小数位,则不限小数位的长度
     *   注意:如果你的金额达到了贰仟万以上,则不推荐使用该方法,否则计算出来的结果会令人大吃一惊
     * @param amount  金额的元进制字符串
     * @return String 金额的分进制字符串
     */
    public static String moneyYuanToFen(String amount) {
        if (isEmpty(amount)) {
            return amount;
        }
        //传入的金额字符串代表的是一个整数
        if (-1 == amount.indexOf(".")) {
            return Integer.parseInt(amount) * 100 + "";
        }
        //传入的金额字符串里面含小数点-->取小数点前面的字符串,并将之转换成单位为分的整数表示
        int money_fen = Integer.parseInt(amount.substring(0, amount.indexOf("."))) * 100;
        //取到小数点后面的字符串
        String pointBehind = (amount.substring(amount.indexOf(".") + 1));
        //amount=12.3
        if (pointBehind.length() == 1) {
            return money_fen + Integer.parseInt(pointBehind) * 10 + "";
        }
        //小数点后面的第一位字符串的整数表示
        int pointString_1 = Integer.parseInt(pointBehind.substring(0, 1));
        //小数点后面的第二位字符串的整数表示
        int pointString_2 = Integer.parseInt(pointBehind.substring(1, 2));
        //amount==12.03,amount=12.00,amount=12.30
        if (pointString_1 == 0) {
            return money_fen + pointString_2 + "";
        } else {
            return money_fen + pointString_1 * 10 + pointString_2 + "";
        }
    }

    /**
     * 金额分转元
     *   注意:如果传入的参数中含小数点,则直接原样返回
     *   该方法返回的金额字符串格式为<code>00.00</code>,其整数位有且至少有一个,小数位有且长度固定为2
     * @param amount  金额的分进制字符串
     * @return String 金额的元进制字符串
     */
    public static String moneyFenToYuan(String amount) {
        if (isEmpty(amount)) {
            return amount;
        }
        if (amount.indexOf(".") > -1) {
            return amount;
        }
        if (amount.length() == 1) {
            return "0.0" + amount;
        } else if (amount.length() == 2) {
            return "0." + amount;
        } else {
            return amount.substring(0, amount.length() - 2) + "." + amount.substring(amount.length() - 2);
        }
    }

    /**
     * 获取一个字符串的简明效果,可以作为手机号码或者身份证号码的隐藏,例如1345***4568
     * @return String 返回的字符串格式类似于"abcd***hijk"
     */
    public static String getStringSimple(String data) {
        return data.substring(0, 4) + "***" + data.substring(data.length() - 4);
    }

    /**
     * 将字符串加密,一般用于密码加密
     * @param str 传入普通字符串
     * @return 返回加密之后的字符串
     */
    public static String password(String str) {
        if (str == null) {return null;}
        String password = null;
        try {
            password = ConfigTools.encrypt(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return password;
    }

    /**
     * 开启定时任务
     * @param date 触发时间
     */
    public static void timing(Date date){
        Timer timer = new Timer();
        timer.schedule(new RemindTask(), date);

    }

    /**
     * 前台响应Map模型
     * @param list 参数
     * @param rowCount 总行数  c
     * @return
     */
    public static Map<String, Object> maps(List list, Long rowCount) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("code", 0); // 放入 code ，0
        map.put("msg", ""); // 放入msg “”
        map.put("count", rowCount); // 放入总行数
        map.put("data", list);// 放入参数
        return map;
    }

    /**
     * 前台响应
     * @param map
     * @param row
     * @param log
     * @return
     */
    public Map<String, Object> rowMap(Map<String, Object> map, int row, OaLog log) {
        if (row > 0) {
            map.put("code", 1);
            map.put("log", "操作成功");
            logService.addLog(log);
        } else {
            map.put("code", 0);
            map.put("log", "操作失败");
        }
        return map;
    }

    public Map<String, Object> errorMap(Map<String, Object> map, OaLog log) {
        map.put("code", 500);
        map.put("log", log.getLogBody());
        map.put("msg", "发生了错误请联系管理员");
        logService.addLog(log);
        return map;
    }

    public void errorMap(OaLog log) {
        logService.addLog(log);
    }

    public List<ThreeVo> createTree(List<ThreeVo> nodes) {
        if (nodes == null || nodes.size() < 1){
            return null;
        }
        // 根节点自定义，但是要和pid对应好
        List<ThreeVo> nodeList = new ArrayList<>();
        // 将所有节点添加到多叉树中
        for (ThreeVo node : nodes) {
            // 根节点自定义，但是要和pid对应好
            if (node.getSuperId().equals(0L)) {
                // 向根添加一个节点
                nodeList.add(node);
            } else {
                for (ThreeVo item : nodes) {
                    if (item.getValue().equals(node.getSuperId())) {
                        item.getChildren().add(node);
                        item.setData(item.getChildren());
                        break ;
                    }
                }
            }
        }

        return nodeList;
    }

    /**
     *  编号
     * @param clientIdentity 尾号
     * @param type 开头
     * @param length 所需要的长度
     * @return 编号
     */
    public static String clientIdentity(String clientIdentity,String type,Integer length) {
       //6
        int y = length - clientIdentity.length();
        StringBuffer cid = new StringBuffer(type);
        for (int i = 0; i < y; i++) {
            cid.append("0");
        }
        cid.append(clientIdentity);
        return cid.toString();
    }

    public static String autoClientIdentity(String count){
         String model = "RF00000000";
         int y = model.length()-count.length();
         StringBuffer cid  = new StringBuffer(model.substring(0,y));
         cid.append(count) ;
        return  cid.toString();

    }



    public static void main(String[] args) {
        System.out.println(Tools.autoClientIdentity("20"));
        System.out.println("测试！！！！！！！！！！！！！！！！！！！！！");
    }
}
